#ifndef __DVC_DR16_H__
#define __DVC_DR16_H__

/*=============================Include========================================*/
#include <limits.h>
#include "drv_uart.h"
/*==============================ExportedMacros================================*/
// 拨动开关位置
#define SWITCH_UP (1)
#define SWITCH_DOWN (2)
#define SWITCH_MIDDLE (3)

// 按键开关位置
#define KEY_FREE (0)
#define KEY_PRESSED (1)

// 键位宏定义
#define KEY_W 0
#define KEY_S 1
#define KEY_A 2
#define KEY_D 3
#define KEY_SHIFT 4
#define KEY_CTRL 5
#define KEY_Q 6
#define KEY_E 7
#define KEY_R 8
#define KEY_F 9
#define KEY_G 10
#define KEY_Z 11
#define KEY_X 12
#define KEY_C 13
#define KEY_V 14
#define KEY_B 15
/*=============================ExportedTypes==================================*/
typedef enum dr16_status {
	DR16_DISABLE = 0,
	DR16_ENABLE,
} dr16_status_e;

typedef enum switch_status {
	UP = 0,
	TRIG_UP_MIDDLE,
	TRIG_MIDDLE_UP,
	MIDDLE,
	TRIG_MIDDLE_DOWN,
	TRIG_DOWN_MIDDLE,
	DOWN,
} switch_status_e;

typedef enum key_status {
	FREE = 0,
	TRIG_FREE_PRESSED,
	TRIG_PRESSED_FREE,
	PRESSED,
} key_status_e;

typedef struct dr16_uart_data {
	uint64_t channel_0 : 11;
	uint64_t channel_1 : 11;
	uint64_t channel_2 : 11;
	uint64_t channel_3 : 11;
	uint64_t switch_2 : 2;
	uint64_t switch_1 : 2;
	int16_t mouse_X;
	int16_t mouse_Y;
	int16_t mouse_Z;
	uint64_t mouse_left : 8;
	uint64_t mouse_right : 8;
	uint64_t key : 16;
	uint64_t channel_Yaw : 11;
} __packed dr16_uart_data_t;

typedef struct dr16_data {
	float right_X;
	float right_Y;
	float left_X;
	float left_Y;
	switch_status_e left_switch;
	switch_status_e right_switch;
	float mouse_X;
	float mouse_Y;
	float mouse_Z;
	key_status_e mouse_left;
	key_status_e mouse_right;
	key_status_e key[16];
	float yaw;
} __packed dr16_data_t;

class DR16 {
  
   public:
	void init(UART_HandleTypeDef *_huart);

	inline float get_right_X();
	inline float get_right_Y();
	inline float get_left_X();
	inline float get_left_Y();
	inline switch_status_e get_left_switch();
	inline switch_status_e get_right_switch();
	inline float get_mouse_X();
	inline float get_mouse_Y();
	inline float get_mouse_Z();
	inline key_status_e get_mouse_left();
	inline key_status_e get_mouse_right();
	inline key_status_e get_key_W();
	inline key_status_e get_key_S();
	inline key_status_e get_key_A();
	inline key_status_e get_key_D();
	inline key_status_e get_key_Shift();
	inline key_status_e get_key_Ctrl();
	inline key_status_e get_key_Q();
	inline key_status_e get_key_E();
	inline key_status_e get_key_R();
	inline key_status_e get_key_F();
	inline key_status_e get_key_G();
	inline key_status_e get_key_Z();
	inline key_status_e get_key_X();
	inline key_status_e get_key_C();
	inline key_status_e get_key_V();
	inline key_status_e get_key_B();
	inline float get_yaw();

	void UART_RxCallback(uint8_t *_rx_data);
	void TIM1msMod50_Alive_PeriodElapsedCallback();

   protected:
	uart_manager_t *uart_manager;

	float rocker_offset = 1024.0f;
	float rocker_num = 660.0f;

	dr16_uart_data_t pre_uart_rx_data;

	uint32_t flag = 0;
	uint32_t pre_flag=0;

	dr16_status_e dr16_status = DR16_ENABLE;

	dr16_data_t data;

	void judge_switch(switch_status_e *_switch, uint8_t _status,
	                  uint8_t _pre_status);
	void judge_key(key_status_e *_key, uint8_t _status, uint8_t _pre_status);
	void data_pross();
};
/*=============================ExportedDefinitions============================*/

/*=============================ExportedFunctionDeclarations===================*/
float DR16::get_right_X() { return data.right_X; }
float DR16::get_right_Y() { return data.right_Y; }
float DR16::get_left_X() { return data.left_X; }
float DR16::get_left_Y() { return data.left_Y; }
switch_status_e DR16::get_left_switch()
{
	return data.left_switch;
}
switch_status_e DR16::get_right_switch() { return data.right_switch; }
float DR16::get_mouse_X()
{
	return data.mouse_X;
}
float DR16::get_mouse_Y()
{
	return data.mouse_Y;
}
float DR16::get_mouse_Z() { return data.mouse_Z; }
key_status_e DR16::get_mouse_left()
{
	return data.mouse_left;
 }
key_status_e DR16::get_mouse_right()
{
	return data.mouse_right;
}
key_status_e DR16::get_key_W()
{
	return data.key[KEY_W];
}
key_status_e DR16::get_key_S() { return data.key[KEY_S]; }
key_status_e DR16::get_key_A() { return data.key[KEY_A]; }
key_status_e DR16::get_key_D() { return data.key[KEY_D]; }
key_status_e DR16::get_key_Shift() { return data.key[KEY_SHIFT]; }
key_status_e DR16::get_key_Ctrl() { return data.key[KEY_CTRL]; }
key_status_e DR16::get_key_Q() { return data.key[KEY_Q]; }
key_status_e DR16::get_key_E() { return data.key[KEY_E]; }
key_status_e DR16::get_key_R() { return data.key[KEY_R]; }
key_status_e DR16::get_key_F() { return data.key[KEY_F]; }
key_status_e DR16::get_key_G() { return data.key[KEY_G]; }
key_status_e DR16::get_key_Z() { return data.key[KEY_Z]; }
key_status_e DR16::get_key_X() { return data.key[KEY_X]; }
key_status_e DR16::get_key_C() { return data.key[KEY_C]; }
key_status_e DR16::get_key_V() { return data.key[KEY_V]; }
key_status_e DR16::get_key_B() { return data.key[KEY_B]; }
float DR16::get_yaw()
{
	return data.yaw;
}

#endif

/*========================COPYRIGHT(C) CCUT-DAMOCLES==========================*/
